package com.lzq.mq.nameserver.replication;

import com.alibaba.fastjson2.JSON;
import com.lzq.mq.common.coder.TcpMsg;
import com.lzq.mq.common.enums.NameServerEventCode;
import com.lzq.mq.nameserver.common.CommonCache;
import com.lzq.mq.nameserver.event.model.SlaveHeartBeatEvent;
import com.lzq.mq.nameserver.event.model.StartReplicationEvent;
import io.netty.channel.Channel;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.TimeUnit;

/**
 * 从节点向主节点发送心跳任务
 */
@Slf4j
public class SlaveReplicationHeartBeatTask extends ReplicationTask  {

    public SlaveReplicationHeartBeatTask(String taskName) {
        super(taskName);
    }

    @Override
    public void startTask() {


        // 等待连接
        int retryCount = 0;
        long waitTime = 1000; // 初始等待时间100毫秒
        while (CommonCache.getMasterConnection() == null || !CommonCache.getMasterConnection().isActive()) {
            if (retryCount >= 3) {
                throw new RuntimeException("等待主节点连接超时，已重试" + retryCount + "次");
            }
            try {
                TimeUnit.MILLISECONDS.sleep(waitTime);
                waitTime *= 2; // 等待时间逐步延长
                retryCount++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                throw new RuntimeException("等待主节点连接时被中断", e);
            }
        }

        // 向主节点发送注册请求, 对当前节点开启同步任务(登录)
        StartReplicationEvent startReplicationEvent = new StartReplicationEvent();
        startReplicationEvent.setUser(CommonCache.getNameserverProperties().getNameserverUser());
        startReplicationEvent.setPassword(CommonCache.getNameserverProperties().getNameserverPwd());
        TcpMsg startReplicationMsg = new TcpMsg(
                NameServerEventCode.START_REPLICATION.getCode(),
                JSON.toJSONBytes(startReplicationEvent)
        );
        CommonCache.getMasterConnection().writeAndFlush(startReplicationMsg);

        log.info("启动从节点心跳任务！");
        while (true) {
            try {
                TimeUnit.SECONDS.sleep(3);
                //发送数据给到主节点
                Channel channel = CommonCache.getMasterConnection();
                TcpMsg tcpMsg = new TcpMsg(NameServerEventCode.SLAVE_HEART_BEAT.getCode(), JSON.toJSONBytes(new SlaveHeartBeatEvent()));
                channel.writeAndFlush(tcpMsg);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
}
